package com.syezon.wifikey.wifi;

import android.arch.lifecycle.MutableLiveData;
import android.content.Context;
import android.net.NetworkInfo;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.Build;

import com.syezon.android.base.utils.LogUtils;
import com.syezon.android.base.utils.ToastUtils;
import com.syezon.wifikey.app.WiFiKeyApp;
import com.syezon.wifikey.pwd.info.SaveWifiPwdInfo;
import com.syezon.wifikey.pwd.viewmodel.MyPwdViewModel;
import com.syezon.wifikey.utils.GpsUtil;
import com.syezon.wifikey.utils.Utils;
import com.syezon.wifikey.utils.WifiUtil;
import com.syezon.wifikey.wifi.info.WifiConnectionInfo;
import com.syezon.wifikey.wifi.info.WifiInfo;
import com.syezon.wifikey.wifi.receiver.SimpleConnectChangeObserver;
import com.syezon.wifikey.wifi.receiver.WiFiConnectReceiver;

import java.util.List;


/**
 * Created by Administrator on 2018/9/14.
 */

public class WifiConnectService {

    public static final String TAG_LOG = WifiConnectService.class.getSimpleName();

    private static WifiConnectService wifiConnectService;

    private WifiInfo mCurrentConnect;

    private ConnectObserver connectObserver = new ConnectObserver();

    private MutableLiveData<WifiInfo> wifiBeanMutableLiveData = new MutableLiveData<>();
    private MutableLiveData<WifiConnectionInfo> wifiConnectionInfoMutableLiveData = new MutableLiveData<>();
    private MutableLiveData<Boolean> showConnectedAdLiveData = new MutableLiveData<>();
    private boolean isFirstConnected = true;

    private WifiConnectService() {
        WiFiConnectReceiver.registerNetworkStateReceiver(Utils.getApp());
        WiFiConnectReceiver.registerObserver(connectObserver);
    }

    public static WifiConnectService getInstance() {
        if (wifiConnectService == null) {
            synchronized (WifiConnectService.class) {
                if (wifiConnectService == null) {
                    wifiConnectService = new WifiConnectService();
                }
            }
        }
        return wifiConnectService;
    }

    public void reset() {
        isFirstConnected = true;
        mCurrentConnect = null;
        showConnectedAdLiveData.postValue(false);
    }


    public MutableLiveData<WifiConnectionInfo> getWifiConnectionInfoMutableLiveData() {
        return wifiConnectionInfoMutableLiveData;
    }

    public void connect(WifiInfo wifiInfo) {
        try {
            //关闭wifi
            if (wifiInfo != null) {
                if (wifiInfo.isConfig() && wifiInfo.getWifiConfiguration() != null && wifiInfo.getWifiConfiguration().networkId > 0) {
                    WifiUtil.connectToConfiguredNetwork(wifiInfo.getWifiConfiguration().networkId);
                } else {
                    WifiUtil.disableAllWifiConfig();
                    WifiManager manager = (WifiManager) Utils.getApp().getApplicationContext().getSystemService(Context.WIFI_SERVICE);
                    int id = -1;
                    int type = WifiUtil.getLockIntType(wifiInfo.getScanResult().capabilities);
                    final WifiConfiguration config = WifiUtil.CreateWifiInfo(manager, wifiInfo.getSsid()
                            , wifiInfo.getPwd(), type);
                    try {
                        id = manager.addNetwork(config);
                    } catch (NullPointerException var12) {
                    }
                    if (id != -1) {
                        //设置priority
                        int max_pri = WifiUtil.getMaxPriority(manager);
                        max_pri = max_pri < 99999 ? max_pri + 1 : 99999;
                        config.priority = max_pri;
                        manager.updateNetwork(config);
                        boolean isConnect = WifiUtil.connectToConfiguredNetwork(id);
                    }
                }

                mCurrentConnect = wifiInfo;
            }
        } catch (Exception e) {
        }
    }

    public WifiConnectionInfo getCurrentConnectionInfo() {
        WifiConnectionInfo wifiConnectionInfo = new WifiConnectionInfo();
        NetworkInfo wifiInfo = WifiUtil.getConnectedWifiNetInfo();
        if (wifiInfo != null && wifiInfo.getDetailedState() == NetworkInfo.DetailedState.CONNECTED) {
            wifiConnectionInfo.setConnected(true);
            wifiConnectionInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED);
            wifiConnectionInfo.setWifiInfo(wifiInfo);
            String wifiSSID = WifiUtil.getWifiSSID();
            if (wifiSSID != null) {
                if (!wifiSSID.contains("unknown ssid")) {
                    wifiSSID = WifiUtil.formatSSID(wifiSSID);
                    wifiConnectionInfo.setSsid(wifiSSID);
                } else {
                    wifiConnectionInfo.setSsid("unknown ssid");
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                        if (!GpsUtil.isGpsOPen()) {
                            wifiConnectionInfo.setGpsDeny(true);
                        }
                    }
                }
            } else {
                wifiConnectionInfo.setSsid("未知WiFi");
            }
            boolean savePwd = MyPwdViewModel.getInstance().isSavePwd(wifiConnectionInfo.getSsid());
            if (savePwd) {
                wifiConnectionInfo.setSavePwd(true);
            } else {
                wifiConnectionInfo.setSavePwd(false);
            }
        } else {
            wifiConnectionInfo.setConnected(false);
            wifiConnectionInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED);
            wifiConnectionInfo.setWifiInfo(null);
        }
        return wifiConnectionInfo;
    }

    private void refreshConnectionInfo(WifiConnectionInfo wifiConnectionInfo) {
        wifiConnectionInfoMutableLiveData.setValue(wifiConnectionInfo);
    }

    private class ConnectObserver extends SimpleConnectChangeObserver {
        @Override
        public void onStateCONNECTED(NetworkInfo wifiInfo, String ssid) {
            if (mCurrentConnect != null &&
                    ((wifiInfo != null && WifiUtil.formatSSID(wifiInfo.getExtraInfo()).equals(mCurrentConnect.getSsid())) ||
                            (ssid != null && ssid.equals(mCurrentConnect.getSsid())))) {
                getSaveWifiList(mCurrentConnect.getSsid());
                if (isFirstConnected) {
                    showConnectedAdLiveData.postValue(true);
                    isFirstConnected = false;
                } else {
                    ToastUtils.showShort("连接成功！");
                }
                mCurrentConnect = null;
            }
        }

        public void getSaveWifiList(String ssid) {
            try {
                List<SaveWifiPwdInfo> all = WiFiKeyApp.getDatabase().getWifiPwdDao().getAll();
                for (int i = 0; all != null && i < all.size(); i++) {
                    SaveWifiPwdInfo saveWifiPwdInfo = all.get(i);
                    if (saveWifiPwdInfo.getSsid().equals(ssid)) {
                        int connectTime = saveWifiPwdInfo.getConnectTime();
                        connectTime++;
                        saveWifiPwdInfo.setConnectTime(connectTime);
                        WiFiKeyApp.getDatabase().getWifiPwdDao().update(saveWifiPwdInfo);
                        break;
                    }
                }
                MyPwdViewModel.getInstance().getSaveWifiList();
            } catch (Exception e) {

            }
        }

        @Override
        public void onConnectedChange(NetworkInfo.DetailedState state, NetworkInfo wifiInfo, String ssid) {
            super.onConnectedChange(state, wifiInfo, ssid);
            WifiConnectionInfo currentConnectionInfo = getCurrentConnectionInfo();
            currentConnectionInfo.setDetailedState(state);
            currentConnectionInfo.setWifiInfo(wifiInfo);
            if (state == NetworkInfo.DetailedState.CONNECTED) {
                currentConnectionInfo.setConnected(true);
            } else if (state == NetworkInfo.DetailedState.DISCONNECTED) {
                currentConnectionInfo.setConnected(false);
            }
            LogUtils.dTag(TAG_LOG, "当前连接的WiFi信息 : " + currentConnectionInfo);
            refreshConnectionInfo(currentConnectionInfo);
            WifiListUtils.getInstance().updateWifiList();
            MyPwdViewModel.getInstance().getSaveWifiList();
        }
    }
}
